from flask import Flask
from flask import jsonify
from flask import request
import requests
import json
import mysql.connector
from mysql.connector import Error
from pypinyin import Style, pinyin

app = Flask(__name__)
insert_url = "http://113.31.111.86:19003/knowledge1/insert_data/"
delete_url = "http://113.31.111.86:19003/knowledge1/delete_data/"
compare_url = "http://113.31.111.86:19003/knowledge1/compare_sim_question/"
mapping_url = "http://113.31.111.86:19003/knowledge1/get_project_base/"
build_project_url = "http://113.31.111.86:19003/knowledge1/build_project/"
delete_project_url = "http://113.31.111.86:19003/knowledge1/delete_project/"
build_base_url = "http://113.31.111.86:19003/knowledge1/build_base/"
delete_base_url = "http://113.31.111.86:19003/knowledge1/delete_data/"
update_group_url = "http://113.31.111.86:19003/knowledge1/update_group_name/"


# 数据库配置
db_config = {
    "host": "113.31.111.86",
    "port": 19009,
    "user": "root",
    "password": "UnidteVdfZwfFERW8nZp5@20210628Hz",
    "database": "llm_data_milvus_final",
}


# 创建数据库连接
def db_connection():
    conn = None
    try:
        conn = mysql.connector.connect(**db_config)
    except Error as e:
        print(e)
    return conn


def formal_name(name):
    return name.replace("-", "_").replace("——", "_")


@app.route("/create_sim_question/", methods=["POST"])
def insert_sim_question():
    data = request.get_json()
    if "question" in data:
        if data["question"] and data["question"] == "":
            return jsonify(
                {"code": 400, "message": "Parameter question should be string and the content should be not empty!",
                 "data": None})
        question_list = [data["question"]]
    else:
        return jsonify({"code": 400, "message": "Parameter question should be given!", "data": None})
    if "question_id" in data:
        question_id_list = [data["question_id"]]
    else:
        return jsonify({"code": 400, "message": "Parameter question_id should be given!", "data": None})
    if "answer" in data:
        answer_list = [data["answer"]]
    else:
        return jsonify({"code": 400, "message": "Parameter answer should be given!", "data": None})
    if "question_extend" in data:
        question_extend_list = [data["question_extend"]]
    else:
        question_extend_list = [[]]

    # qa or faq 默认为qa
    if "qaType" in data:
        qa_type = data["qaType"]
        if qa_type == "FAQ":
            suffix = "faq"
        elif qa_type == "DOC":
            suffix = "qa"
        else:
            return jsonify({"code": 400, "message": "Parameter qaType should be FAQ or DOC!", "data": None})
    else:
        return jsonify({"code": 400, "message": "Parameter qaType should be given!", "data": None})
    # project
    if "firstGroupName" in data:
        project_name_zh = data["firstGroupName"]
    else:
        return jsonify({"code": 400, "message": "Parameter firstGroupName should be given!", "data": None})
    # group
    if "secondGroupName" in data:
        group_name_zh = data["secondGroupName"]
    # else:
    #     return jsonify({"code": 400, "message": "Parameter secondGroupName should be given!", "data": None})

    # base
    if "thirdGroupName" in data:
        base_name_zh = data["thirdGroupName"]
        res = requests.post(mapping_url,
                            data={"project_name_zh": project_name_zh, "base_name_zh": base_name_zh, "suffix": suffix})
        res = res.json()
        if res["status"] == 200:
            base_name = res["base_name"]
            project_name = res["project_name"]
        else:
            return jsonify({"code": 400, "message": res["message"], "data": None})
    else:
        return jsonify({"code": 400, "message": "Parameter thirdGroupName should be given!", "data": None})

    insert_data = {
        "text": json.dumps(question_list),
        "text_uid": json.dumps(question_id_list),
        "detail_text": json.dumps(answer_list),
        "embedding": json.dumps(["m3e-base"]),
        "meta_data": json.dumps([{}]),
        "source": json.dumps(["sim_ques_ext"]),
        "project": json.dumps([project_name]),
        "base": json.dumps([base_name]),
        "base_type": json.dumps([""]),
        "sim_text": json.dumps(question_extend_list),
    }
    try:
        res = requests.post(insert_url, data=insert_data)
        print(res.json())
    except Exception as e:
        print("error", e)
        return jsonify({"code": 400, "message": "insert fail!", "data": None})
    return jsonify({"code": 200, "message": "insert success!", "data": None})


@app.route("/delete_sim_question/", methods=["POST"])
def delete_sim_question():
    data = request.get_json()
    if "question_id" in data:
        question_id_list = [data["question_id"]]
    else:
        return jsonify({"code": 400, "message": "Parameter question_id should be given!", "data": None})

    # qa or faq 默认为qa
    if "qaType" in data:
        qa_type = data["qaType"]
        if qa_type == "FAQ":
            suffix = "faq"
        elif qa_type == "DOC":
            suffix = "qa"
        else:
            return jsonify({"code": 400, "message": "Parameter qaType should be FAQ or DOC!", "data": None})
    else:
        return jsonify({"code": 400, "message": "Parameter qaType should be given!", "data": None})

    delete_data = {
        "embedding": "m3e-base",
        "question_uid": json.dumps(question_id_list)
    }
    try:
        res = requests.post(delete_url, data=delete_data)
        print(res.json())
    except Exception as e:
        print("error", e)
        return jsonify({"code": 400, "message": "delete fail!", "data": None})
    return jsonify({"code": 200, "message": "delete success!", "data": None})


@app.route("/update_sim_question/", methods=["POST"])
def update_sim_question():
    data = request.get_json()
    if "question" in data:
        if data["question"] and data["question"] == "":
            return jsonify(
                {"code": 400, "message": "Parameter question should be string and the content should be not empty!",
                 "data": None})
        question = data["question"]
    else:
        return jsonify({"code": 400, "message": "Parameter question should be given!", "data": None})
    if "question_id" in data:
        question_id = data["question_id"]
    else:
        return jsonify({"code": 400, "message": "Parameter question_id should be given!", "data": None})
    if "answer" in data:
        answer = data["answer"]
    else:
        return jsonify({"code": 400, "message": "Parameter answer should be given!", "data": None})
    if "question_extend" in data:
        sim_text = data["question_extend"]
    else:
        sim_text = []
    # qa or faq
    if "qaType" in data:
        qa_type = data["qaType"]
        if qa_type == "FAQ":
            suffix = "faq"
        elif qa_type == "DOC":
            suffix = "qa"
        else:
            return jsonify({"code": 400, "message": "Parameter qaType should be FAQ or DOC!", "data": None})
    else:
        return jsonify({"code": 400, "message": "Parameter qaType should be given!", "data": None})
    # project
    if "firstGroupName" in data:
        project_name_zh = data["firstGroupName"]
    else:
        return jsonify({"code": 400, "message": "Parameter firstGroupName should be given!", "data": None})
    # group
    if "secondGroupName" in data:
        group_name_zh = data["secondGroupName"]
    # else:
    #     return jsonify({"code": 400, "message": "Parameter secondGroupName should be given!", "data": None})

    # base
    if "thirdGroupName" in data:
        base_name_zh = data["thirdGroupName"]
        res = requests.post(mapping_url,
                            data={"project_name_zh": project_name_zh, "base_name_zh": base_name_zh, "suffix": suffix})
        res = res.json()
        if res["status"] == 200:
            base_name = res["base_name"]
            project_name = res["project_name"]
        else:
            return jsonify({"code": 400, "message": res["message"], "data": None})
    else:
        return jsonify({"code": 400, "message": "Parameter thirdGroupName should be given!", "data": None})
    try:
        sim_text = data["question_extend"]
        compare_data = {
            "text": question,
            "text_uid": question_id,
            "detail_text": answer,
            "project": project_name,
            "base": base_name,
            "sim_text": json.dumps(sim_text)
        }
        compare_res = requests.post(compare_url, data=compare_data)
        if compare_res.status_code == 200:
            compare_res = compare_res.json()
            if "insert" in compare_res:
                is_insert = compare_res["insert"]
            else:
                is_insert = False
            print("compare_res", compare_res)
            if compare_res["status"] == 200:
                update_question = compare_res["data"]["update_question"]
                add_sim_item = compare_res["data"]["add_sim_item"]
                delete_sim_item = compare_res["data"]["delete_sim_item"]
                if delete_sim_item or update_question == "true":
                    # 删除
                    del_uid_list = []
                    if update_question == "true":
                        del_uid_list.append(data["question_id"])
                    del_uid_list.extend([item["extend_id"] for item in delete_sim_item])
                    del_res = requests.post(delete_url, data={
                        "question_uid": json.dumps(del_uid_list),
                        "project": project_name,
                        "base": base_name,
                        "embedding": "m3e-base",
                        "is_association": "false",
                    })
                    print("del_res", del_res.json())
                if add_sim_item or is_insert:
                    # 插入
                    insert_data = {
                        "text": json.dumps([question]),
                        "text_uid": json.dumps([question_id]),
                        "detail_text": json.dumps([answer]),
                        "embedding": json.dumps(["m3e-base"]),
                        "meta_data": json.dumps([{}]),
                        "source": json.dumps(["sim_ques_ext"]),
                        "project": json.dumps([project_name]),
                        "base": json.dumps([base_name]),
                        "base_type": json.dumps([""]),
                        "sim_text": json.dumps([add_sim_item]),
                        "is_normalize": True
                    }

                    insert_res = requests.post(insert_url, data=insert_data)
                    print("insert_res", insert_res.json())
            else:
                return jsonify({"code": 400, "message": "update fail!", "data": None})
        else:
            return jsonify({"code": 400, "message": "update fail!", "data": None})
    except Exception as e:
        print("error", e)
        return jsonify({"code": 400, "message": "update fail!", "data": None})
    return jsonify({"code": 200, "message": "update success!", "data": None})


# @app.route("/delete_group/", methods=["POST"])
# def delete_group():
#     data = request.get_json()
#     if "parentGroupId" in data:
#         parentGroupId = data["parentGroupId"]
#     else:
#         return jsonify({"code": 400, "message": "Parameter parentGroupId should be given!", "data": None})
#     if "groupName" in data:
#         groupName = data["groupName"]
#     else:
#         return jsonify({"code": 400, "message": "Parameter groupName should be given!", "data": None})
#     if "groupId" in data:
#         groupName = data["groupName"]
#     else:
#         return jsonify({"code": 400, "message": "Parameter groupId should be given!", "data": None})

#     if "qaType" in data:
#         qa_type = data["qaType"]
#         if qa_type == "FAQ":
#             suffix = "faq"
#         elif qa_type == "DOC":
#             suffix = "qa"
#         else:
#             return jsonify({"code": 400, "message": "Parameter qaType should be FAQ or DOC!", "data": None})
#     else:
#         return jsonify({"code": 400, "message": "Parameter qaType should be given!", "data": None})


# @app.route("/build_group/", methods=["POST"])
# def build_group():
#     data = request.get_json()
#     if "parentGroupId" in data:
#         parentGroupId = data["parentGroupId"]
#     else:
#         return jsonify({"code": 400, "message": "Parameter parentGroupId should be given!", "data": None})
#     if "groupName" in data:
#         groupName = data["groupName"]
#     else:
#         return jsonify({"code": 400, "message": "Parameter groupName should be given!", "data": None})
#     if "groupId" in data:
#         groupName = data["groupName"]
#     else:
#         return jsonify({"code": 400, "message": "Parameter groupId should be given!", "data": None})

#     if "qaType" in data:
#         qa_type = data["qaType"]
#         if qa_type == "FAQ":
#             suffix = "faq"
#         elif qa_type == "DOC":
#             suffix = "qa"
#         else:
#             return jsonify({"code": 400, "message": "Parameter qaType should be FAQ or DOC!", "data": None})
#     else:
#         return jsonify({"code": 400, "message": "Parameter qaType should be given!", "data": None})


@app.route("/create_update_record/", methods=["POST"])
def create_update_record():
    data = request.get_json()
    if "desc" in data:
        desc = data["desc"]
    else:
        return jsonify({"code": 400, "message": "Parameter desc should be given!", "data": None})
    if "thirdId" in data:
        thirdId = data["thirdId"]
    else:
        return jsonify({"code": 400, "message": "Parameter thirdId should be given!", "data": None})
    if "thirdParentId" in data:
        thirdParentId = data["thirdParentId"]
    else:
        return jsonify({"code": 400, "message": "Parameter thirdParentId should be given!", "data": None})
    if "type" in data:
        qa_type = data["type"]
    else:
        return jsonify({"code": 400, "message": "Parameter type should be given!", "data": None})
    if "level" in data:
        level = data["level"]
    else:
        return jsonify({"code": 400, "message": "Parameter level should be given!", "data": None})
    
    if "name" in data:
        name = data["name"]
    else:
        name = None
    if "delFlag" in data:
        delFlag = data["delFlag"]
    else:
        delFlag = 1
    
    try:
        if name is None:
            # basename 拼音 转换
            if level == 1:
                name = (
                        "".join(
                            [
                                phone[0]
                                for phone in pinyin(
                                desc,
                                style=Style.NORMAL,
                                strict=False,
                                neutral_tone_with_five=True,
                            )
                            ]
                        )
                )
            else:
                name = (
                        "".join(
                            [
                                phone[0]
                                for phone in pinyin(
                                desc,
                                style=Style.NORMAL,
                                strict=False,
                                neutral_tone_with_five=True,
                            )
                            ]
                        )
                        + "_"
                        + str(thirdId)[-4:]
                        + "_"
                        + str(qa_type)
                )
        name = formal_name(name)

        conn = db_connection()
        cursor = conn.cursor()
        # 判断是否已有记录
        cursor.execute("SELECT * FROM table_platform_kgbase WHERE thirdId = %s and status = 1", (thirdId,))
        rows = cursor.fetchall()
        # 已存在，不用新的name，取要原来的name，只需要修改desc即可
        if rows:
            cursor.execute(
                """
                UPDATE table_platform_kgbase 
                SET `desc` = %s, type = %s, thirdId = %s, thirdParentId = %s, status = %s, level = %s, delFlag = %s
                WHERE thirdId=%s and status = 1
            """,
                (
                    desc,
                    qa_type,
                    thirdId,
                    thirdParentId,
                    1,
                    level,
                    delFlag,
                    thirdId,
                ),
            )
            conn.commit()
            if level == 1:
                project_name = formal_name(rows[0][3])
                data = {"project_name": project_name, "project_desc": desc}
                try:
                    res = requests.post(build_project_url, data=data).json()
                    if res["status"] != 200:
                        return jsonify({
                            "status": True,
                            "code": 204,
                            "message": "创建失败！",
                        })
                except Exception as e:
                    print("error", e)
                    return jsonify({
                        "status": True,
                        "code": 204,
                        "message": "创建失败！",
                    })
            elif level == 2:
                cursor.execute("SELECT * FROM table_platform_kgbase WHERE thirdId = %s and status = 1",
                               (thirdParentId,))
                level1_rows = cursor.fetchall()
                project_name = formal_name(level1_rows[0][3])

                old_group_name = rows[0][2]
                new_group_name = desc
                data = {"project_name": project_name, "old_group_name": old_group_name, "new_group_name": new_group_name}
                res = requests.post(update_group_url, data=data)

            elif level == 3:
                base_name = formal_name(rows[0][3])
                cursor.execute("SELECT * FROM table_platform_kgbase WHERE thirdId = %s and status = 1",
                               (thirdParentId,))
                level2_rows = cursor.fetchall()
                group_name = level2_rows[0][2]
                cursor.execute("SELECT * FROM table_platform_kgbase WHERE thirdId = %s and status = 1",
                               (level2_rows[0][6],))
                level1_rows = cursor.fetchall()
                project_name = formal_name(level1_rows[0][3])
                data = {
                    "project_name": project_name,
                    "group_name": group_name,
                    "base_name": base_name,
                    "base_desc": desc,
                    "embedding_type": "m3e-base"
                }
                try:
                    res = requests.post(build_base_url, data=data).json()
                    if res["status"] != 200:
                        return jsonify({
                            "status": True,
                            "code": 204,
                            "message": "创建失败！",
                        })
                except Exception as e:
                    print("error", e)
                    return jsonify({
                        "status": True,
                        "code": 204,
                        "message": "创建失败！",
                    })
        # 不存在
        else:
            # 判断name和type列是否存在相同的记录
            cursor.execute("SELECT * FROM table_platform_kgbase WHERE name = %s and type = %s and level = %s and status = 1", (name, qa_type, level, ))
            exists_rows = cursor.fetchall()
            if exists_rows:
                # 若存在，直接返回错误
                # print("error", e)
                return jsonify({
                    "status": True,
                    "code": 204,
                    "message": "创建失败，存在name相同的分组！",
                })
            if level == 1:
                cursor.execute(
                    """
                    INSERT INTO table_platform_kgbase (id, parentId, `desc`, name, type, thirdId, thirdParentId, status, level, delFlag)
                    VALUES (%s,%s, %s, %s, %s, %s, %s, %s, %s, %s)
                """,
                    (
                        qa_type * 1000 + 100,
                        0,
                        desc,
                        name,
                        qa_type,
                        thirdId,
                        thirdParentId,
                        1,
                        level,
                        delFlag,
                    ),
                )
                conn.commit()
                # todo 一级创建project
                project_name = formal_name(name)
                data = {"project_name": project_name, "project_desc": desc}
                try:
                    res = requests.post(build_project_url, data=data).json()
                    if res["status"] != 200:
                        return jsonify({
                            "status": True,
                            "code": 204,
                            "message": "创建失败！",
                        })
                except Exception as e:
                    print("error", e)
                    return jsonify({
                        "status": True,
                        "code": 204,
                        "message": "创建失败！",
                    })
            elif level == 2:
                cursor.execute(
                    """
                    INSERT INTO table_platform_kgbase (id, parentId, `desc`, name, type, thirdId, thirdParentId, status, level, delFlag)
                    VALUES (%s,%s, %s, %s, %s, %s, %s, %s, %s, %s)
                """,
                    (
                        (qa_type * 1000 + 100) * 100 + 1,
                        qa_type * 1000 + 100,
                        desc,
                        name,
                        qa_type,
                        thirdId,
                        thirdParentId,
                        1,
                        level,
                        delFlag,
                    ),
                )
                conn.commit()
                # 二级不用创建
            elif level == 3:
                cursor.execute(
                    """
                    INSERT INTO table_platform_kgbase (id, parentId, `desc`, name, type, thirdId, thirdParentId, status, level, delFlag)
                    VALUES (%s,%s, %s, %s, %s, %s, %s, %s, %s, %s)
                """,
                    (
                        ((qa_type * 1000 + 100) * 100 + 1) * 100 + 1,
                        (qa_type * 1000 + 100) * 100 + 1,
                        desc,
                        name,
                        qa_type,
                        thirdId,
                        thirdParentId,
                        1,
                        level,
                        delFlag,
                    ),
                )
                conn.commit()
                cursor.execute("SELECT * FROM table_platform_kgbase WHERE thirdId = %s and status = 1",
                               (thirdParentId,))
                rows = cursor.fetchall()
                group_name = rows[0][2]
                cursor.execute("SELECT * FROM table_platform_kgbase WHERE thirdId = %s and status = 1", (rows[0][6],))
                rows = cursor.fetchall()
                project_name = formal_name(rows[0][3])
                base_name = formal_name(name)
                # todo 三级创建base
                data = {
                    "project_name": project_name,
                    "group_name": group_name,
                    "base_name": base_name,
                    "base_desc": desc,
                    "embedding_type": "m3e-base"
                }
                try:
                    res = requests.post(build_base_url, data=data).json()
                    if res["status"] != 200:
                        return jsonify({
                            "status": True,
                            "code": 204,
                            "message": "创建失败！",
                        })
                except Exception as e:
                    print("error", e)
                    return jsonify({
                        "status": True,
                        "code": 204,
                        "message": "创建失败！",
                    })
        conn.commit()
        cursor.close()
        conn.close()
        result = {
            "status": True,
            "code": 200,
            "message": "创建成功",
        }
    except Exception as e:
        result = {
            "status": True,
            "code": 204,
            "message": str(e),
        }
    return jsonify(result)


@app.route("/delete_record/", methods=["POST"])
def delete_record():
    data = request.get_json()
    if "thirdId" in data:
        idx = data["thirdId"]
    else:
        return jsonify({"code": 400, "message": "Parameter thirdId should be given!", "data": None})
    if "type" in data:
        type_value = data["type"]
    else:
        return jsonify({"code": 400, "message": "Parameter type should be given!", "data": None})
    print(idx, type_value)
    try:
        result = {
            "status": True,
            "code": 200,
            "message": "删除成功",
        }
        conn = db_connection()
        cursor = conn.cursor()
        # 查找是否存在
        cursor.execute("SELECT * FROM table_platform_kgbase WHERE thirdId = %s and type = %s and status = 1",
                       (idx, type_value,))
        rows = cursor.fetchall()
        if rows:
            level = rows[0][8]
            if level != 3:
                cursor.execute("SELECT * FROM table_platform_kgbase WHERE thirdParentId = %s and type = %s and status = 1", (idx, type_value, ))
                child_rows = cursor.fetchall()
                if child_rows:
                    # 有子表，禁止删除
                    result = {
                        "status": True,
                        "code": 209,
                        "message": '该分组不可删除，其下包含子表！',
                    }
                    return jsonify(result)

                    # 判断有没有有下级
            # delFlag非0则status置为0
            if rows[0][-1]:
                cursor.execute(
                    """
                    UPDATE table_platform_kgbase
                    SET status = 0
                    WHERE thirdId=%s and type = %s and status = 1
                """,
                    (idx, type_value),
                )
                conn.commit()
                # todo 删除project/base？等待反馈是否添加
                # if level == 1:
                #     # 删除项目
                #     try:
                #         res = requests.post(delete_project_url, data={"project_name": formal_name(rows[0][3])})
                #     except Exception as e:
                #         print("error:", e)
                #         result['message'] = '删除失败'
                # elif level == 3:
                #     base_name = formal_name(rows[0][3])
                #     cursor.execute("SELECT * FROM table_platform_kgbase WHERE thirdId = %s and status = 1", (rows[0][6],))
                #     level2_rows = cursor.fetchall()
                #     group_name = level2_rows[0][2]
                #     cursor.execute("SELECT * FROM table_platform_kgbase WHERE thirdId = %s and status = 1", (level2_rows[0][6],))
                #     level1_rows = cursor.fetchall()
                #     project_name = formal_name(level1_rows[0][3])
                #     print(project_name, base_name)
                #     data = {
                #         "project": project_name,
                #         "delete_base": base_name,
                #     }
                #     try:
                #         res = requests.post(delete_base_url, data=data)
                #     except Exception as e:
                #         print("error:", e)
                #         result['message'] = '删除失败'
                    
            else:
                result['message'] = '该分组不可删除'
        else:
            result['message'] = '该分组不可删除'
        conn.commit()
        cursor.close()
        conn.close()


    except Exception as e:
        result = {
            "status": True,
            "code": 204,
            "message": str(e),
        }
    return jsonify(result)


if __name__ == '__main__':
    # app.config['JSON_AS_ASCII'] = False
    app.json.ensure_ascii = False
    app.run(host="0.0.0.0", port=19103, debug=False)


